/* -*- C -*- */

#cpu power4

#include <stdio.h>
#include <stdlib.h>


typedef int (*pifi)(int);


pifi rpnCompile(char *expr)
{
  insn *code= (insn *)calloc(64, sizeof(insn));
  int top= 3;
#ifdef _IBMR2
  code = code + 2;
#endif
  #[	.org	code  ]#;

  while (*expr)
    {
      char  buf[32];
      int n, tmp ;
      if (sscanf(expr, "%[0-9]%n", buf, &n))
	{
	  expr+= n - 1;
	  if (top == 10)
	    {
	      fprintf(stderr, "expression too complex");
	      exit(0);
	    }
	  ++top; tmp = atoi(buf);
	  #[
	    subf  r(top), r(top), r(top)
	    ori   r(top), r(top), (tmp)  
	  ]#;
	}
      else if (*expr == '+')
	{ --top; #[	add	r(top), r(top), r(top+1)	]# }
      else if (*expr == '-')
	{ --top; #[		subf	r(top), r(top+1), r(top)	]# }
      else if (*expr == '*')
	{ --top; #[		mullw	r(top), r(top), r(top+1)	]# }
      else if (*expr == '/')
	{ --top; #[		divw	r(top), r(top), r(top+1)	]# }
      else
	{
	  fprintf(stderr, "cannot compile: %s\n", expr);
	  abort();
	}
      ++expr;
    }

  if (3 != top)
    {
      fprintf(stderr, "stack error\n");
      abort();
    }

  #[	blr	  ]#;
#ifdef _IBMR2
  {
    long * codeB;
    codeB = (long *) code;
    codeB[0] = (long) code2;
  }
#endif
  iflush(code, hpbcg_asm_pc);
  if ((int)(hpbcg_asm_pc - code) >= 64)
    {
      fprintf(stderr, "expression too complex");
      exit(0);
    }
  return (pifi)code;
}
